#ifndef NIM_HEADER
#define NIM_HEADER
#include "nim.h";
#endif

#ifndef IOSTREAM
#define IOSTREAM

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#endif

using namespace std;

void play_Nim(SOCKET lsock , bool Side, char* service)
{
	string board;
	string temp, comment, forfeit; 
	int tempRocks, tempPile;
	bool validInput = false;
	bool firstTime = true;
	char inputChar = ' ';
	char host[MAX_HOSTNAME+1];
	char recvBuf[MAX_RECV_BUF+1];
	char sendBuf[MAX_SEND_BUF+1];
	char hPort[MAX_SERVICE+1];
	char move[MAX_SEND_BUF];
	bool gameOver = false;
	char boardPacket[MAX_SEND_BUF+1];
	int pileNumber = 0;

	if(Side == true) //if true then client 
	{
		int len = tcp_recv(lsock,recvBuf,MAX_RECV_BUF,host,hPort);
		strcpy_s(boardPacket,MAX_SEND_BUF,recvBuf);
		gameEnd:
		while( gameOver != true )
		{
			int i = 0;
			while (boardPacket[i]!='\0')
			{
				board=board+boardPacket[i];
				++i;
			}
			//Find number of piles
			temp = board.substr(0,1);
			int numberPiles = atoi(temp.c_str());
			int *rockPiles = new int[numberPiles];
			//Fill rockPiles array with correct amount of rocks
			pileNumber = numberPiles;
			for(int i = 0, j = 1; i < numberPiles; i++, j += 2)
			{
				temp = board.substr(j,2);
				rockPiles[i] = atoi(temp.c_str());
			}
			//Ouput Dashes
			cout << "NIM board:" << endl;
			for(int i = 0; i < 80; i++)
				cout << "-";

			//Output amount in piles
			for(int i = 0; i < numberPiles; i++)
			{
				cout << "Rock Pile #" << i+1 << " -> ";
				int intemp = 0;
				for(int k = 0; k < rockPiles[i]; k++)
				{
					cout << "*"<<" ";
					intemp++;
				}
				int space = 20 - intemp;
				while (space != 0)
				{
					space --;
					cout <<"  ";
				}
				cout <<"  <" << setw (2) << intemp <<">"  "  <- "<< "Rock Pile #" <<  i+1 ;
				cout << endl;
			}
			//Output Dashes
			for(int i = 0; i < 80; i++)
				cout << "-";

			//if(yourTurn)
			cout << endl << "Your turn." << endl;
			while(inputChar != 'R')
			{	
				cout << "Enter first letter of one of the following commands <C,F,H, or R>." << endl;
				cout << "Command <Chat, Forfeit, Help, Remove-rocks>? ";
				//First input
				cin >> temp;
				temp = temp.substr(0,1);
				inputChar = temp[0];
				inputChar = toupper(inputChar);
				//Illegal Input?
				while(inputChar != 'C' && inputChar != 'F' && inputChar != 'H' && inputChar != 'R')
				{
					//Put in boardPacket right!
					cout << "Illegal Command! Try again." << endl;
					cout << "Enter first letter of one of the following commands <C,F,H, or R>." << endl;
					cout << "Command <Chat, Foreit, Help, Remove-rocks>? ";
					cin >> temp;
					temp = temp.substr(0,1);
					inputChar = temp[0];
					inputChar = toupper(inputChar);
				}
				//Handling Comments, Forfeits, Help
				switch(inputChar)
				{
					case 'C':
						cout << "Comment? ";
						cin >> comment;
						comment.insert(0,1,'C');
						char message[MAX_SEND_BUF];
						for(int i = 0; i < comment.length(); i++)
							message[i] = comment[i];
								
						message[comment.length()] = '\0';
						tcp_send(lsock,message,MAX_SEND_BUF,host,service);
						break;
					case 'F':
						cout << "Do you want to forfeit this game <Y/N>? ";
						cin >> forfeit;
						break;
					case 'H':
						cout << endl << endl << "Command Meaning" << endl << "------- -------" << endl;
						cout << "   c    Send a comment to network opponent." << endl;
						cout << "   f    Forfeit the game.." << endl;
						cout << "   h    Display this help message." << endl;
						cout << "   r    Select some rocks to remove from a pile." << endl;
						cout << endl;
						break;
					default:
						break;
				}
				if(_stricmp(forfeit.c_str(),"Y") == 0)
				{
					char awesome[MAX_SEND_BUF] = "F\0";
					tcp_send(lsock,awesome,MAX_SEND_BUF,host,service);
					cout << endl << "Way to forfeit" << endl;
					gameOver = true;
					goto gameEnd;
				}
			}
			inputChar = ' ';
			//Handling removal of rock piles
			while(validInput == false)
			{
				cout << "From which pile would you like to remove some rocks? <1-" << numberPiles << ">? ";
				cin >> tempPile;
				//Is a valid pile?
				while(tempPile < 1 || tempPile > numberPiles)
				{
					cout << "No such pile! Please try again. " << endl;
					cout << "From which pile would you like to remove some rocks? <1-" << numberPiles << ">? ";
					cin >> tempPile;
					//Because array starts at 0 and piles start at 1
				}
				//Is pile empty?
				if(rockPiles[tempPile - 1] <= 0)
					cout << "There are no rocks in pile #" << tempPile<< "! Please try again." << endl;
					
				//Good job you chose a non empty pile
				if(rockPiles[tempPile - 1] > 0)
				{
					cout << "How many rocks would you like to remove? <1-" << rockPiles[tempPile - 1] << ">? ";
					cin >> tempRocks;
					//Are you trying to remove too many or not enough?
					if(tempRocks > rockPiles[tempPile - 1] || tempRocks < 1 || tempRocks > 19)
					{
						cout << "You can't remove " << tempRocks << " rocks from pile #" << tempPile<< " Sillybuns!" << endl;
					}
					//Ahhh the sweet spot
					else
					{
						int i = 0;
						while (boardPacket[i]!='\0')
						{
							board=board+boardPacket[i];
							++i;
						}
						//Find number of piles
						int tempint2=0;
						tempint2=tempPile*2-1;
						string temp2 = board.substr(tempint2,2);
						int numberRocks2 = atoi(temp2.c_str());
						numberRocks2 = numberRocks2-tempRocks;
						char tempint3[MAX_SEND_BUF];
						/*=========================update new board=================================*/
						if(numberRocks2 < 10)
						{
							boardPacket[tempint2]='0';
							itoa (numberRocks2,tempint3,MAX_SEND_BUF);
							boardPacket[tempint2+1]=tempint3[0];
						}
						else
						{
							numberRocks2 = numberRocks2-10;
							itoa (numberRocks2,tempint3,MAX_SEND_BUF);
							boardPacket[tempint2]='1';
							boardPacket[tempint2+1]=tempint3[0];
						}
						board.clear();//clear the board for modified boardpacket
						int g = 0;
						while (boardPacket[g]!='\0')
						{
							board=board+boardPacket[g];
							++g;
						}
						//Find number of piles
						temp = board.substr(0,1);
						int numberPiles = atoi(temp.c_str());
						int *rockPiles = new int[numberPiles];
						//Fill rockPiles array with correct amount of rocks
						for(int i = 0, j = 1; i < numberPiles; i++, j += 2)
						{
							temp = board.substr(j,2);
							rockPiles[i] = atoi(temp.c_str());
						}
						int count2 = 0;
						int numberPiles6 = numberPiles*2;
						//Ouput Dashes
						cout << "NIM board:" << endl;
						for(int i = 0; i < 80; i++)
							cout << "-";
						
						//Output amount in piles
						for(int i = 0; i < numberPiles; i++)
						{
							cout << "Rock Pile #" << i+1 << " -> ";
							int intemp = 0;
							for(int k = 0; k < rockPiles[i]; k++)
							{
								cout << "*"<<" ";
								intemp++;
							}
							int space = 20 - intemp;
							while (space != 0)
							{
								space --;
								cout <<"  ";
							}
							cout <<"  <" << setw (2) << intemp <<">"  "  <- "<< "Rock Pile #" <<  i+1 ;
							cout << endl;
						}
						//Output Dashes
						for(int i = 0; i < 80; i++)
							cout << "-";
							
						board.clear();//clear again for new board next boardPackets
						/*==================convert moves to char to be ready to send======================*/
						itoa (tempPile,move,MAX_SEND_BUF);
						char move2[MAX_SEND_BUF];
						if(tempRocks < 10)
						{
							move[1]='0';						
							itoa (tempRocks,move2,MAX_SEND_BUF);
							move[2]=move2[0];
						}
						else
						{
							int tempRocks2= tempRocks-10;
							itoa (tempRocks2,move2,MAX_SEND_BUF);
							move[1]='1';
							move[2]=move2[0];
						}
						/*==============================================================*/
						tcp_send(lsock,move,MAX_SEND_BUF,host,service);
						//store the move in move string
						//Check for win!
						for( int i = 1; i < numberPiles6+1; i++ )
							if(boardPacket[i] != '0')
								count2++;
							
						if( count2 == 0)
						{
							gameOver = true;
							cout<< "you win!!!!"<<endl;
							closesocket(lsock);
							goto gameEnd;
						}						
						validInput = true;
					}
				}
			}
			validInput = false;
			cout << "Waiting for opponents's move...";			
			//and convert # of pile and # of rock in boardPacket to int
			//and do calculation and put it back to boardPacket for output
			len = tcp_recv(lsock,recvBuf,MAX_RECV_BUF,host,hPort);
			if( _stricmp(recvBuf,"F\0") == 0 )
			{
				cout << "You Win!!!!" << endl;
				gameOver = true;
				goto gameEnd;
			}
			while(recvBuf[0] == 'C')
			{
				string temp;
				temp = recvBuf;
				temp.erase(0,1);
				cout << temp << endl;
				len = tcp_recv(lsock,recvBuf,MAX_RECV_BUF,host,hPort);
			}
			char recvMove[MAX_RECV_BUF];
			strcpy_s(recvMove,MAX_SEND_BUF,recvBuf);
			//convert recvMove to int
			string recvMovestr,tempMovestr,tempboardPacket;
			int p = 0;
			while (recvMove[p]!='\0')
			{
				recvMovestr=recvMovestr+recvMove[p];
				++p;
			}				
			tempMovestr = recvMovestr.substr(0,1);
			int numberPiles3 = atoi(tempMovestr.c_str());
			tempMovestr.clear();
			tempMovestr = recvMovestr.substr(1,2);
			int numberRocks3 = atoi(tempMovestr.c_str());
			tempMovestr.clear();
			int numberPiles4 = numberPiles3*2-1;
			tempboardPacket=tempboardPacket+boardPacket[numberPiles4];
			tempboardPacket=tempboardPacket+boardPacket[numberPiles4+1];
			int boardPacketRock = atoi(tempboardPacket.c_str());
			boardPacketRock = boardPacketRock - numberRocks3;
			//modify boardPacket with recvMove
			char putitBackToboardPacket[MAX_SEND_BUF];
			if(boardPacketRock < 10)
			{
				boardPacket[numberPiles4]='0';						
				itoa (boardPacketRock,putitBackToboardPacket,MAX_SEND_BUF);
				boardPacket[numberPiles4+1]=putitBackToboardPacket[0];
			}
			else
			{
				int boardPacketRock2 = boardPacketRock-10;
				itoa (boardPacketRock2,putitBackToboardPacket,MAX_SEND_BUF);
				boardPacket[numberPiles4]='1';
				boardPacket[numberPiles4+1]=putitBackToboardPacket[0];
			}
			//Check to see if you lose
			int count2 = 0;
			int numberPiles6 = numberPiles*2;
			for( int i = 1; i < numberPiles6+1; i++ )
				if(boardPacket[i] != '0')
					count2++;
							
			if( count2 == 0)
			{
				gameOver = true;
				cout<< endl << "you lose!!!!"<<endl;
				closesocket(lsock);
				goto gameEnd;
			}
		}
	}
	//Server
	else if( Side == false )
	{
		//maybe we could randomlize the number and put it in to 
		char tempintServer[MAX_SEND_BUF];
		board = "3122016";
		int i = 0;
		strcpy (boardPacket, board.c_str());
		boardPacket[7] = '\0';
		//Find number of piles
		temp = board.substr(0,1);
		int numberPiles = atoi(temp.c_str());
		int *rockPiles = new int[numberPiles];
		//Fill rockPiles array with correct amount of rocks
		pileNumber = numberPiles;
		for(int i = 0, j = 1; i < numberPiles; i++, j += 2)
		{
			temp = board.substr(j,2);
			rockPiles[i] = atoi(temp.c_str());
		}
		//Ouput Dashes
		cout << "NIM board:" << endl;
		for(int i = 0; i < 80; i++)	
			cout << "-";
			
		//Output amount in piles
		for(int i = 0; i < numberPiles; i++)
		{
			cout << "Rock Pile #" << i+1 << " -> ";
			int intemp = 0;
			for(int k = 0; k < rockPiles[i]; k++)
			{
				cout << "*"<<" ";
				intemp++;
			}
			int space = 20 - intemp;
			while (space != 0)
			{
				space --;
				cout <<"  ";
			}
				cout <<"  <" << setw (2) << intemp <<">"  "  <- "<< "Rock Pile #" <<  i+1 ;
				cout << endl;
		}
		//Output Dashes
		for(int i = 0; i < 80; i++)
			cout << "-";
			
		/*============================================================*/
		//copy boardPacket to sendBuf to send over
		strcpy_s(sendBuf,MAX_SEND_BUF,boardPacket);
		strcpy_s(hPort,MAX_SERVICE,TCPPORT_NIM);
		int len = tcp_send(lsock,sendBuf,MAX_SEND_BUF,service,hPort);
		cout << "Waiting for opponent's move..." << endl;
		while( gameOver != true )
		{
			len = tcp_recv(lsock,recvBuf,MAX_RECV_BUF,host,hPort);
			if( _stricmp(recvBuf,"F\0") == 0 )
			{
				cout << "You Win!!!!" << endl;
				gameOver = true;
				goto gameEnd;
			}
			while(recvBuf[0] == 'C')
			{
				string temp;
				temp = recvBuf;
				temp.erase(0,1);
				cout << temp << endl;
				len = tcp_recv(lsock,recvBuf,MAX_RECV_BUF,host,hPort);
			}
			char recvMove[MAX_RECV_BUF];
			strcpy_s(recvMove,MAX_SEND_BUF,recvBuf);
			//convert recvMove to int
			string recvMovestr,tempMovestr,tempboardPacket;
			int p = 0;
			while (recvMove[p]!='\0')
			{
				recvMovestr=recvMovestr+recvMove[p];
				++p;
			}				
			tempMovestr = recvMovestr.substr(0,1);
			int numberPiles3 = atoi(tempMovestr.c_str());
			tempMovestr.clear();
			tempMovestr = recvMovestr.substr(1,2);
			int numberRocks3 = atoi(tempMovestr.c_str());
			tempMovestr.clear();
			int numberPiles4 = numberPiles3*2-1;
			tempboardPacket=tempboardPacket+boardPacket[numberPiles4];
			tempboardPacket=tempboardPacket+boardPacket[numberPiles4+1];
			int boardPacketRock = atoi(tempboardPacket.c_str());
			boardPacketRock = boardPacketRock - numberRocks3;
			//modify boardPacket with recvMove
			char putitBackToboardPacket[MAX_SEND_BUF];
			if(boardPacketRock < 10)
			{
				boardPacket[numberPiles4]='0';						
				itoa (boardPacketRock,putitBackToboardPacket,MAX_SEND_BUF);
				boardPacket[numberPiles4+1]=putitBackToboardPacket[0];
			}
			else
			{
				int boardPacketRock2 = boardPacketRock-10;
				itoa (boardPacketRock2,putitBackToboardPacket,MAX_SEND_BUF);
				boardPacket[numberPiles4]='1';
				boardPacket[numberPiles4+1]=putitBackToboardPacket[0];
			}
			//Check to see if you lose
			int count2 = 0;
			int numberPiles6 = numberPiles*2;
			for( int i = 1; i < numberPiles6+1; i++ )
				if(boardPacket[i] != '0')
					count2++;
				
			if( count2 == 0)
			{
				gameOver = true;
				cout<< endl << "you lose!!!!"<<endl;
				closesocket(lsock);
				goto gameEnd;
			}
			board.clear();
			int g = 0;
			while (boardPacket[g]!='\0')
			{
				board=board+boardPacket[g];
				++g;
			}
			//Find number of piles
			temp = board.substr(0,1);
			int numberPiles8 = atoi(temp.c_str());
			int *rockPiles8 = new int[numberPiles8];
			//Fill rockPiles array with correct amount of rocks
			for(int i = 0, j = 1; i < numberPiles8; i++, j += 2)
			{
				temp = board.substr(j,2);
				rockPiles8[i] = atoi(temp.c_str());
			}
			//Ouput Dashes
			cout << "NIM board:" << endl;
			for(int i = 0; i < 80; i++)
				cout << "-";
			
			//Output amount in piles
			for(int i = 0; i < numberPiles8; i++)
			{
				cout << "Rock Pile #" << i+1 << " -> ";
				int intemp = 0;
				for(int k = 0; k < rockPiles8[i]; k++)
				{
					cout << "*"<<" ";
					intemp++;
				}
				int space = 20 - intemp;
				while (space != 0)
				{
					space --;
					cout <<"  ";
				}
				cout <<"  <" << setw (2) << intemp <<">"  "  <- "<< "Rock Pile #" <<  i+1 ;
				cout << endl;
			}
			//Output Dashes
			for(int i = 0; i < 80; i++)
				cout << "-";
			
			cout << endl << "Your turn." << endl;
			while(inputChar != 'R')
			{				
				cout << "Enter first letter of one of the following commands <C,F,H, or R>." << endl;
				cout << "Command <Chat, Foreit, Help, Remove-rocks>? ";
				//First input
				cin >> temp;
				temp = temp.substr(0,1);
				inputChar = temp[0];
				inputChar = toupper(inputChar);
				//Illegal Input?
				while(inputChar != 'C' && inputChar != 'F' && inputChar != 'H' && inputChar != 'R')
				{
					//Put in boardPacket right!
					cout << "Illegal Command! Try again." << endl;
					cout << "Enter first letter of one of the following commands <C,F,H, or R>." << endl;
					cout << "Command <Chat, Foreit, Help, Remove-rocks>? ";
					cin >> temp;
					temp = temp.substr(0,1);
					inputChar = temp[0];
					inputChar = toupper(inputChar);
				}
				//Handling Comments, Forfeits, Help
				switch(inputChar)
				{
					case 'C':
						cout << "Comment? ";
						cin >> comment;
						comment.insert(0,1,'C');
						char message[MAX_SEND_BUF];
						for(int i = 0; i < comment.length(); i++)
							message[i] = comment[i];
						
						message[comment.length()] = '\0';						
						tcp_send(lsock,message,MAX_SEND_BUF,host,service);
						break;
					case 'F':
						cout << "Do you want to forfeit this game <Y/N>? ";
						cin >> forfeit;
						break;
					case 'H':
						cout << endl << endl << "Command Meaning" << endl << "------- -------" << endl;
						cout << "   c    Send a comment to network opponent." << endl;
						cout << "   f    Forfeit the game.." << endl;
						cout << "   h    Display this help message." << endl;
						cout << "   r    Select some rocks to remove from a pile." << endl;
						cout << endl;
						break;
					default:
						break;
				}
				if(_stricmp(forfeit.c_str(),"Y") == 0)
				{
					char awesome[MAX_SEND_BUF] = "F\0";
					tcp_send(lsock,awesome,MAX_SEND_BUF,host,service);
					cout << endl << "Way to forfeit" << endl;
					gameOver = true;
					goto gameEnd;
				}
			}
			inputChar = ' ';
			//Handling removal of rock piles
			while(validInput == false)
			{
				cout << "From which pile would you like to remove some rocks? <1-" << numberPiles << ">? ";
				cin >> tempPile;
				//Is a valid pile?
				while(tempPile < 1 || tempPile > numberPiles)
				{
					cout << "No such pile! Please try again. " << endl;
					cout << "From which pile would you like to remove some rocks? <1-" << numberPiles << ">? ";
					cin >> tempPile;
					//Because array starts at 0 and piles start at 1
				}
				//Is pile empty?
				if(rockPiles[tempPile - 1] <= 0)
					cout << "There are no rocks in pile #" << tempPile<< "! Please try again." << endl;
					
				//Good job you chose a non empty pile
				if(rockPiles[tempPile - 1] > 0)
				{
					cout << "How many rocks would you like to remove? <1-" << rockPiles[tempPile - 1] << ">? ";
					cin >> tempRocks;					
					//Are you trying to remove too many or not enough?
					if(tempRocks > rockPiles[tempPile - 1] || tempRocks < 1 || tempRocks > 19)
						cout << "You can't remove " << tempRocks << " rocks from pile #" << tempPile<< " Sillybuns!" << endl;
					//Ahhh the sweet spot
					else
					{
						board.clear();
						int i = 0;
						while (boardPacket[i]!='\0')
						{
							board=board+boardPacket[i];
							++i;
						}
						//Find number of piles
						int tempint2=0;
						tempint2=tempPile*2-1;
						string temp2 = board.substr(tempint2,2);
						int numberRocks2 = atoi(temp2.c_str());
						numberRocks2 = numberRocks2-tempRocks;
						char tempint3[MAX_SEND_BUF];
						/*=========================update new board=================================*/
						if(numberRocks2 < 10)
						{
							boardPacket[tempint2]='0';									
							itoa (numberRocks2,tempint3,MAX_SEND_BUF);
							boardPacket[tempint2+1]=tempint3[0];
						}
						else
						{
							//int numberRocks2 = 0;
							numberRocks2 = numberRocks2-10;
							itoa (numberRocks2,tempint3,MAX_SEND_BUF);
							boardPacket[tempint2]='1';
							boardPacket[tempint2+1]=tempint3[0];
						}
						board.clear();//clear the board for modified boardpacket
						int g = 0;
						while (boardPacket[g]!='\0')
						{
							board=board+boardPacket[g];
							++g;
						}
						//Find number of piles
						temp = board.substr(0,1);
						int numberPiles = atoi(temp.c_str());
						int *rockPiles = new int[numberPiles];
						//Fill rockPiles array with correct amount of rocks
						for(int i = 0, j = 1; i < numberPiles; i++, j += 2)
						{
							temp = board.substr(j,2);
							rockPiles[i] = atoi(temp.c_str());
						}
						int count2 = 0;
						int numberPiles6 = numberPiles*2;
						//Ouput Dashes
						cout << "NIM board:" << endl;
						for(int i = 0; i < 80; i++)
							cout << "-";
							
						//Output amount in piles
						for(int i = 0; i < numberPiles; i++)
						{
							cout << "Rock Pile #" << i+1 << " -> ";
							int intemp = 0;
							for(int k = 0; k < rockPiles[i]; k++)
							{
								cout << "*"<<" ";
								intemp++;
							}
							int space = 20 - intemp;
							while (space != 0)
							{
								space --;
								cout <<"  ";
							}
							cout <<"  <" << setw (2) << intemp <<">"  "  <- "<< "Rock Pile #" <<  i+1 ;
							cout << endl;
						}
						//Output Dashes
						for(int i = 0; i < 80; i++)
							cout << "-";
							
						board.clear();//clear again for new board next boardPackets						
						/*==================convert moves to char to be ready to send======================*/
						itoa (tempPile,move,MAX_SEND_BUF);
						char move2[MAX_SEND_BUF];
						if(tempRocks < 10)
						{
							move[1]='0';						
							itoa (tempRocks,move2,MAX_SEND_BUF);
							move[2]=move2[0];
						}
						else
						{
							int tempRocks2= tempRocks-10;
							itoa (tempRocks2,move2,MAX_SEND_BUF);
							move[1]='1';
							move[2]=move2[0];
						}
						/*==============================================================*/
						tcp_send(lsock,move,MAX_SEND_BUF,host,service);
						//Check for win!
						for( int i = 1; i < numberPiles6+1; i++ )
							if(boardPacket[i] != '0')
								count2++;
						
						if( count2 == 0)
						{
							gameOver = true;
							cout<< "you win!!!!"<<endl;
							closesocket(lsock);
							goto gameEnd;
						}
						//store the move in move string	
						validInput = true;
					}
				}
			}
			validInput = false;
			cout << "Waiting for opponents's move..." << endl;
			if(len < 0)
			{
				cout << "you lose!!!" << endl;
				gameOver = true;
			}
		}
	}
}
